package edu.cmu.cs.cs214.hw9.client.controllers;

import java.util.EnumMap;
import java.util.Map;

import javax.swing.JFrame;

import edu.cmu.cs.cs214.hw9.client.controllers.eventhandlers.*;
import edu.cmu.cs.cs214.hw9.client.gui.FacelookScreen;

/**
 * Implements a generic controller, which by default handles registration/login events only.
 * The controller manages the logic between the facelook screens and the database.
 */
public class FacelookController {
	private BackendCacheAdapter model;
	private JFrame frame;
	private FacelookScreen view;
	protected Map<Event, EventHandler> eventMap;
	
	/**
	 * Constructs a new controller which links the provided models and screens/views.
	 * 
	 * @param model The database to interface with.
	 * @param frame The JFrame associated with the screen.
	 * @param view The screen that is displayed to the user.
	 */
	public FacelookController(BackendCacheAdapter model, JFrame frame, FacelookScreen view) {
		this.model = model;
		this.frame = frame;
		this.view = view;
		
		// Setup our event map, which maps events to specific event handling code.
		eventMap = new EnumMap<Event, EventHandler>(Event.class);
		eventMap.put(Event.GO_TO_LOGIN, new GotoLoginHandler(this));
		eventMap.put(Event.GO_TO_REGISTRATION, new GotoRegistrationHandler(this));
		eventMap.put(Event.LOGIN, new LoginHandler(this));
		eventMap.put(Event.REGISTER_NEW_USER, new RegistrationHandler(this));
	}
	
	/**
	 * Returns the associated database 
	 * 
	 * @return The database.
	 */
	public BackendCacheAdapter getModel() { return model; }
	
	/**
	 * Returns the JFrame associated with the view.
	 *  
	 * @return Associated JFrame.
	 */
	public JFrame getFrame() { return frame; }
	
	/**
	 * Returns the screen currently viewed by the user.
	 * 
	 * @return The current screen.
	 */
	public FacelookScreen getView() { return view; }
	
	/**
	 * Handle a particular event by spawning its associated event handler
	 * and calling the handleEvent method.
	 * 
	 * @param e Event to handle.
	 */
	public void handleEvent(FacelookEvent e) {
		// Look for the event in our event map.
		if (eventMap.containsKey(e.getEvent())) {
			EventHandler h = eventMap.get(e.getEvent());
			h.handleEvent(e.getParam());
		} else {
			throw new RuntimeException("Invalid event encountered!");
		}
	}
}
